Skip to content

feat: Add Annotated Tag Push Support#1139

Open
fabiovincenzi wants to merge 39 commits into
finos:mainfrom
fabiovincenzi:push-tags
Open

feat: Add Annotated Tag Push Support#1139
fabiovincenzi wants to merge 39 commits into
finos:mainfrom
fabiovincenzi:push-tags

Conversation

@fabiovincenzi

@fabiovincenzi fabiovincenzi commented Aug 4, 2025

Copy link
Copy Markdown
Contributor

Description:
This PR introduces end-to-end support for annotated tag pushes

  • Split the push pipeline into separate branchPushChain and tagPushChain.
  • Update getChain() to select the correct chain based on action.type and presence of action.tag.
  • Render a dedicated “Tag Details” table when viewing a tag push instead of the commit diff.

Fixes #986

@netlify

netlify Bot commented Aug 4, 2025

Copy link
Copy Markdown

Deploy Preview for endearing-brigadeiros-63f9d0 canceled.

Name Link
🔨 Latest commit cf14102
🔍 Latest deploy log https://app.netlify.com/projects/endearing-brigadeiros-63f9d0/deploys/6a34fbbc21be1900081025c1

@codecov

codecov Bot commented Aug 6, 2025

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 85.67%. Comparing base (fc23d58) to head (cf14102).

Additional details and impacted files
@@            Coverage Diff             @@
##             main    #1139      +/-   ##
==========================================
+ Coverage   85.38%   85.67%   +0.28%     
==========================================
  Files          83       83              
  Lines        7878     7967      +89     
  Branches     1312     1342      +30     
==========================================
+ Hits         6727     6826      +99     
+ Misses       1123     1114       -9     
+ Partials       28       27       -1     

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.
  • 📦 JS Bundle Analysis: Save yourself from yourself by tracking and limiting bundle sizes in JS merges.

Comment thread src/proxy/processors/push-action/parsePush.ts Outdated
Comment thread src/proxy/processors/push-action/parsePush.ts Outdated
Comment thread src/proxy/processors/push-action/parsePush.ts Outdated
Comment thread src/proxy/processors/push-action/parsePush.ts Outdated
Comment thread src/proxy/processors/push-action/parsePush.ts Outdated

@jescalada jescalada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The core flow seems to work correctly! Just a few edge cases and an integration issue with the checkEmptyBranch that might be worth refactoring.

Also, we will be merging #973 soon which will likely cause a few conflicts here... Might want an extra pair of eyes to make sure everything is good to merge.

@fabiovincenzi

Copy link
Copy Markdown
Contributor Author

Updated with the latest changes of main and manually tested also with gitlab

Comment thread src/proxy/chain.ts Outdated
action = await proc.pre.parseAction(req);
// 2) Parse the push payload first to detect tags/branches
if (action.type === RequestType.PUSH) {
action = await proc.push.parsePush(req, action);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm not sure if I misunderstood the flow here, but isn't parsePush executing twice when pushing branches? Seems it executes here, and once again as part of the branchPushChain.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Regardless, it seems the push flow is working as expected - just not sure if this is running twice or if the parsePush prevents the double execution somehow.

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

A change above removed proc.push.parsePush from the branchPushChain, but I don't know why./ I think it should just be the first processor in both the branchPushChain and tagPushChain

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kriswest I've spent some time trying to understand/refactor this, and I think I see the reasoning: It makes sense for parsePush to be separate to the other actions, since it's the only place where we can determine what kind of Git object (tag, branch, etc.) is getting pushed. And it also makes sense to have different chains for different Git objects, since they are often processed differently (we don't check for commit content for tag pushes, etc.).

Since parsePush is the "odd one out" (just another pre-processor for pushes), we should probably specify this special case in our docs, and refactor our code accordingly (moving it into /src/proxy/processors/pre-processor).

I think the confusion comes from calling parsePush an Action/processor in the chain when it has become a pre-processor exclusively for pushes.


Wondering if there's a better solution from an architecture point of view. 🤔

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pinging @fabiovincenzi and @finos/git-proxy-maintainers for ideas

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thansk @jescalada, I see the issue and yes we need to start parsing the push to establish type, makes sense. I agree with moving it over the pre-processors folder and keeping it out of the individual chains..

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

THanks for looking at this @jescalada - yes I missed that it was doing the parsing that detected the push type. I agree with moving this to the pre-processors folder and keeping it out of the individual chains. The comments added help a lot.

Will we ever have to handle mixed pushes of both branches and tags... Doh, yes: https://stackoverflow.com/questions/3745135/push-git-commits-tags-simultaneously

We'll need to handle that case - we could detect and reject it for now?

@jescalada jescalada left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good to me! I tested the tags and regular push flow and both work as expected with the new updates 👍🏼

Just a comment on the parsePush which I'm not sure if it's executing once or twice on pushes.

@jescalada jescalada requested a review from a team August 27, 2025 10:10
@jescalada

Copy link
Copy Markdown
Contributor

As we're modifying the proxy logic, another pair of eyes here would be super helpful! 👀 @finos/git-proxy-maintainers

@kriswest

Copy link
Copy Markdown
Contributor

Resolved comments that have been dealt with already

Comment thread src/proxy/processors/pre-processor/parsePush.ts
Comment thread src/ui/utils/pushUtils.ts
* @param {PushData} pushData - The push data
* @return {string} The reference name to display
*/
export const getRefToShow = (pushData: PushData): string => {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'm getting an error here when pushing an empty tag via: git tag test-tag-1 && git push test-tag-1:

image

This also creates errors on the dashboard:

image

I tried patching this by modifying the call to trimPrefixRefsHeads to default to empty strings like such:

  return trimPrefixRefsHeads(pushData.branch || '');

And now the empty tag push is visible on the dashboard, but only on the "All" tab, whereas I expected it to show on the "Pending" tab.

image

Notably, the reason for failure is checkUserPushPermission failing to find the email associated with the push:

image

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

If non-annotated tag support isn't included, we should perhaps check and throw a more descriptive error as the current one is misleading 👍🏼

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Apparently the term is 'lightweight' tag. See https://git-scm.com/book/en/v2/Git-Basics-Tagging#:~:text=Git%20supports%20two%20types%20of,objects%20in%20the%20Git%20database for some reading on them.

It would probably be good to support these or throw a specific error message on them, but we'll need to classify them. We have an issue with them as the awful hack used to cover the fact we don't actually know the pusher (use the last committer email) fails here as theres no commit data. Hence, perhaps we should NOT support these for now and add an error message and a TODO until we fix that architectural flaw.

Comment thread src/proxy/chain.ts Outdated
Comment thread src/proxy/chain.ts Outdated
action = await proc.pre.parseAction(req);
// 2) Parse the push payload first to detect tags/branches
if (action.type === RequestType.PUSH) {
action = await proc.push.parsePush(req, action);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@kriswest I've spent some time trying to understand/refactor this, and I think I see the reasoning: It makes sense for parsePush to be separate to the other actions, since it's the only place where we can determine what kind of Git object (tag, branch, etc.) is getting pushed. And it also makes sense to have different chains for different Git objects, since they are often processed differently (we don't check for commit content for tag pushes, etc.).

Since parsePush is the "odd one out" (just another pre-processor for pushes), we should probably specify this special case in our docs, and refactor our code accordingly (moving it into /src/proxy/processors/pre-processor).

I think the confusion comes from calling parsePush an Action/processor in the chain when it has become a pre-processor exclusively for pushes.


Wondering if there's a better solution from an architecture point of view. 🤔

Comment thread src/proxy/chain.ts Outdated
action = await proc.pre.parseAction(req);
// 2) Parse the push payload first to detect tags/branches
if (action.type === RequestType.PUSH) {
action = await proc.push.parsePush(req, action);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pinging @fabiovincenzi and @finos/git-proxy-maintainers for ideas

@jescalada

Copy link
Copy Markdown
Contributor

LGTM so far, the general flow is still working as expected, and the double parsePush issue is fixed 👍🏼

Just a few issues to iron out:

  • Empty tag pushes give a missing user error which is misleading
  • We should figure out whether to refactor the chains to contain parsePush again (which makes intuitive sense)
    • Otherwise, we can make parsePush a pre-processor, considering it pre-processes pushes to define what type of Git object is being pushed, and consequentially which push chain must be executed (branchPushChain, tagPushChain or something else).

Comment thread src/proxy/actions/Action.ts Outdated
@fabiovincenzi

Copy link
Copy Markdown
Contributor Author

All review comments have been addressed. Ready for a final look! @kriswest @jescalada

action.branch = parsedRefs[0].refName;
}

// Use the first ref's commit range for the action id

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

These comments should stay...

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add support for pushing tags git push --tags Add support for pushing tags git push --tags

4 participants